package com.chaodriod.common.utils;

import android.util.Log;

/**
 * 自定义的日志处理器。提供
 * 1. 日志等级管理
 * 2. 默认使用类名作为Tag，方法名，行数信息
 * 3. msg前面自动添加：方法名（行数）。
 * 4. 支持超长Log
 * Created by CHEN on 2018/4/4.
 */

public class ALog {

    private static boolean isDebug = Utils.isDebug();
    /**
     * Application TAG,use "logcat -s TAG"
     */
    private static String TAG = "ALOG";

    /**
     * log level
     */
    private static int LOG_LEVEL = Log.VERBOSE;

    private static int LOG_MAXLENGTH = 2000;

    /**
     * set log level, default Log.VERBOSE
     *
     * @param level
     */
    public static void setLogLevel(int level) {
        LOG_LEVEL = level;
    }

    /**
     * set application TAG, default "ALOG"
     *
     * @param tag
     */
    public static void setAppTAG(String tag) {
        TAG = tag;
    }

    private static String getSimpleName(StackTraceElement stackTrace) {
        String className = stackTrace.getClassName();
        int dot = className.lastIndexOf('.');
        if (dot != -1) {
            className = className.substring(dot + 1);
        }
        return className;
    }


    public static void e(String msg) {
        e(null, msg);
    }

    /**
     * Thread.currentThread().stackTrace[4]//kotlin
     * Throwable().stackTrace[2]//kotlin
     * new Exception().getStackTrace()[1]
     * new Throwable().getStackTrace()[2]//java
     * Thread.currentThread().getStackTrace()[2]//java
     */
    public static void e(String tag, String msg) {
        if (isDebug && LOG_LEVEL <= Log.VERBOSE) {
//            Throwable().stackTrace.forEachIndexed { index, stackTraceElement ->
//                Log.e(tag, "!!!$index ${stackTraceElement.className}!!!")
//                Log.e(tag, "!!!$index ${stackTraceElement.methodName}!!!")
//            }
            StackTraceElement stackTrace = new Throwable().getStackTrace()[2];
            String logtag = tag;
            if (logtag == null) {
                logtag = getSimpleName(stackTrace);
            }
            String message = stackTrace.getMethodName() + "(" + stackTrace.getLineNumber() + "): " + msg;
            if (message.length() <= LOG_MAXLENGTH) {
                Log.e(logtag, message);
            } else {
                int length = message.length();
                int start = 0;
                int end = LOG_MAXLENGTH;
                for (int i = 0; i < 100; i++) {
                    //剩下的文本还是大于规定长度则继续重复截取并输出
                    if (length > end) {
                        Log.e(logtag + i, message.substring(start, end));
                        start = end;
                        end += LOG_MAXLENGTH;
                    } else {
                        Log.e(logtag, message.substring(start, length));
                        break;
                    }
                }
            }
        }
    }

    public static void w(String msg) {
        w(null, msg);
    }

    public static void w(String tag, String msg) {
        if (isDebug && LOG_LEVEL <= Log.VERBOSE) {
            StackTraceElement stackTrace = new Throwable().getStackTrace()[2];
            String logtag = tag;
            if (logtag == null) {
                logtag = getSimpleName(stackTrace);
            }
            String message = stackTrace.getMethodName() + "(" + stackTrace.getLineNumber() + "): " + msg;
            if (message.length() <= LOG_MAXLENGTH) {
                Log.w(logtag, message);
            } else {
                int length = message.length();
                int start = 0;
                int end = LOG_MAXLENGTH;
                for (int i = 0; i < 100; i++) {
                    //剩下的文本还是大于规定长度则继续重复截取并输出
                    if (length > end) {
                        Log.w(logtag + i, message.substring(start, end));
                        start = end;
                        end += LOG_MAXLENGTH;
                    } else {
                        Log.w(logtag, message.substring(start, length));
                        break;
                    }
                }
            }
        }
    }

    public static void i(String msg) {
        i(null, msg);
    }

    public static void i(String tag, String msg) {
        if (isDebug && LOG_LEVEL <= Log.VERBOSE) {
            StackTraceElement stackTrace = new Throwable().getStackTrace()[2];
            String logtag = tag;
            if (logtag == null) {
                logtag = getSimpleName(stackTrace);
            }
            String message = stackTrace.getMethodName() + "(" + stackTrace.getLineNumber() + "): " + msg;
            if (message.length() <= LOG_MAXLENGTH) {
                Log.i(logtag, message);
            } else {
                int length = message.length();
                int start = 0;
                int end = LOG_MAXLENGTH;
                for (int i = 0; i < 100; i++) {
                    //剩下的文本还是大于规定长度则继续重复截取并输出
                    if (length > end) {
                        Log.i(logtag + i, message.substring(start, end));
                        start = end;
                        end += LOG_MAXLENGTH;
                    } else {
                        Log.i(logtag, message.substring(start, length));
                        break;
                    }
                }
            }
        }
    }

    public static void d(String msg) {
        d(null, msg);
    }

    public static void d(String tag, String msg) {
        if (isDebug && LOG_LEVEL <= Log.VERBOSE) {
            StackTraceElement stackTrace = new Throwable().getStackTrace()[2];
            String logtag = tag;
            if (logtag == null) {
                logtag = getSimpleName(stackTrace);
            }
            String message = stackTrace.getMethodName() + "(" + stackTrace.getLineNumber() + "): " + msg;
            if (message.length() <= LOG_MAXLENGTH) {
                Log.d(logtag, message);
            } else {
                int length = message.length();
                int start = 0;
                int end = LOG_MAXLENGTH;
                for (int i = 0; i < 100; i++) {
                    //剩下的文本还是大于规定长度则继续重复截取并输出
                    if (length > end) {
                        Log.d(logtag + i, message.substring(start, end));
                        start = end;
                        end += LOG_MAXLENGTH;
                    } else {
                        Log.d(logtag, message.substring(start, length));
                        break;
                    }
                }
            }
        }
    }

    public static void v(String msg) {
        v(null, msg);
    }

    public static void v(String tag, String msg) {
        if (isDebug && LOG_LEVEL <= Log.VERBOSE) {
            StackTraceElement stackTrace = new Throwable().getStackTrace()[2];
            String logtag = tag;
            if (logtag == null) {
                logtag = getSimpleName(stackTrace);
            }
            String message = stackTrace.getMethodName() + "(" + stackTrace.getLineNumber() + "): " + msg;
            if (message.length() <= LOG_MAXLENGTH) {
                Log.v(logtag, message);
            } else {
                int length = message.length();
                int start = 0;
                int end = LOG_MAXLENGTH;
                for (int i = 0; i < 100; i++) {
                    //剩下的文本还是大于规定长度则继续重复截取并输出
                    if (length > end) {
                        Log.v(logtag + i, message.substring(start, end));
                        start = end;
                        end += LOG_MAXLENGTH;
                    } else {
                        Log.v(logtag, message.substring(start, length));
                        break;
                    }
                }
            }
        }
    }

}